package com.bestcem.xm.user.controller;

import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.common.core.enums.ReqErrorCodeEnum;
import com.bestcem.xm.component.security.annotation.XmAuth;
import com.bestcem.xm.component.security.context.SecurityContextHolder;
import com.bestcem.xm.component.security.dto.TokenDTO;
import com.bestcem.xm.user.annotations.CheckGroupLock;
import com.bestcem.xm.user.constant.BusinessConstant;
import com.bestcem.xm.user.controller.vo.group.GroupLevelUpperVO;
import com.bestcem.xm.user.controller.vo.group.UpdateGroupLevelVO;
import com.bestcem.xm.user.controller.vo.group.UserGroupLevelOldVO;
import com.bestcem.xm.user.controller.vo.group.UserGroupLevelVO;
import com.bestcem.xm.user.service.UserGroupLevelService;
import com.bestcem.xm.user.service.dto.group.*;
import com.bestcem.xm.user.util.business.GroupLevelUtil;
import com.bestcem.xm.user.util.business.GroupLockUtil;
import com.bestcem.xm.user.util.convert.UserGroupLevelConvert;
import com.bestcem.xm.user.util.converter.UserGroupLevelConverter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import java.util.Objects;

/**
 * 用户层级服务接口提供
 *
 * @author jishuo.yan <jishuo.yan@idiaoyan.com>
 * @version v1.0
 * @date 2021/12/29 16:01
 */
@Slf4j
@RestController
@RequestMapping(value = "/user/grouplevels")
public class UserGroupLevelController {

    @Resource
    private UserGroupLevelService userGroupLevelService;

    @Resource
    private GroupLockUtil groupLockUtil;

    @Resource
    private UserGroupLevelConvert userGroupLevelConvert;

    /**
     * 获取用户有权限查看的层级列表
     */
    @XmAuth
    @GetMapping()
    public XmResultJson<List<UserGroupLevelOldVO>> getGroupLevel(@RequestParam(name = "levelId", required = false) String levelId) {
        TokenDTO currentToken = SecurityContextHolder.getToken();
        ServiceResult<List<UserGroupLevelOldVO>> serviceResult = userGroupLevelService.getLevels(currentToken, levelId);
        return XmResultJson.success(serviceResult.getData());
    }

    /**
     * 设置层级显示字段
     *
     * @param displayDTOList 层级显示字段
     * @return com.bestcem.xm.util.XmResultJson<java.lang.Object>
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/2/10 23:18
     */
    @CheckGroupLock
    @PutMapping("/display")
    @Validated
    public XmResultJson<Object> setLevelDisplay(@RequestBody @Valid ValidList<DisplayDTO> displayDTOList) {
        TokenDTO currentToken = SecurityContextHolder.getToken();
        ServiceResult<Object> serviceResult = userGroupLevelService.setLevelDisplay(displayDTOList, currentToken);
        if (serviceResult.isSuccess()) {
            return XmResultJson.success();
        } else {
            return XmResultJson.fail(serviceResult.getErrorData(), serviceResult.getMsg());
        }
    }

    /**
     * 查询层级列表【包含显示字段】
     *
     * @return com.bestcem.xm.util.XmResultJson<java.util.List < com.bestcem.xm.user.group.entity.pojo.UserGroupLevelVO>>
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/2/11 14:33
     */
    @XmAuth
    @GetMapping(value = "/display")
    public XmResultJson<List<UserGroupLevelVO>> getGroupLevelDisplay(@RequestParam(required = false, defaultValue = "false") boolean all) {
        TokenDTO currentToken = SecurityContextHolder.getToken();
        ServiceResult<List<UserGroupLevelDTO>> serviceResult = userGroupLevelService.getLevelsAndDisplay(currentToken, all);
        return XmResultJson.success(UserGroupLevelConverter.levelDTOToVO(serviceResult.getData()));
    }

    /**
     * 编辑/删除层级
     *
     * @param levelVO 接口入参
     * @return com.bestcem.xm.util.XmResultJson<java.lang.Object>
     * @author Linzhijian <zhijian.lin@idiaoyan.com>
     * @date 2022/04/02 17:09
     */
    @CheckGroupLock
    @PostMapping("/update")
    public XmResultJson<Object> updateGroupLevel(@RequestBody @Validated UpdateGroupLevelVO levelVO) {
        String orgId = SecurityContextHolder.getToken().getOrgId();
        String userId = SecurityContextHolder.getToken().getUserId();
        if (levelVO.getLevelData().size() > BusinessConstant.USER_LEVEL_MAX_COUNT) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_FORMAT, "公司层级数不能大于15层");
        }
        if (levelVO.getLevelData().size() < BusinessConstant.USER_LEVEL_MIN_COUNT) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_FORMAT, "公司层级数不能小于2层");
        }
        for (GroupLevelDTO levelDatum : levelVO.getLevelData()) {
            if (GroupLevelUtil.checkLevelNameInvalid(levelDatum.getGroupLevelName())) {
                return XmResultJson.fail(ReqErrorCodeEnum.PARAM_FORMAT, String.format("层级 %s 格式错误", levelDatum.getGroupLevelName()));
            }
        }
        UpdateGroupLevelDTO updateGroupLevelDTO = userGroupLevelConvert.updateLevelVO2dto(levelVO);
        // 是否是系统管理员或者高级管理员
        Boolean admin = NumberUtils.INTEGER_ONE.equals(SecurityContextHolder.getToken().getSuperRole()) || NumberUtils.INTEGER_ONE.equals(SecurityContextHolder.getToken().getIsSenior());
        updateGroupLevelDTO.setIsAdmin(admin);
        // 加锁
        groupLockUtil.lock(orgId);
        ServiceResult<Boolean> result = ServiceResult.success();
        try {
            result = userGroupLevelService.updateGroupLevel(updateGroupLevelDTO, orgId, userId);
        } catch (Exception e) {
            log.error("更新层级失败", e);
        } finally {
            // 解锁
            groupLockUtil.unlock(orgId);
        }
        if (result.isSuccess()) {
            return XmResultJson.success(result.getData());
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());
    }

    /**
     * 获取某个组所在层级及以上层级，从高到低排列
     *
     * @param groupId
     * @return com.bestcem.xm.util.XmResultJson<java.util.List < com.bestcem.xm.user.controller.vo.group.GroupLevelUpperVO>>
     * @params groupID: 为空时返回所有层级，为currentuser时返回当前用户所在层级及以上层级
     * apps_mysql/user/handlers.py:2437
     * @author Linzhijian <zhijian.lin@idiaoyan.com>
     * @date 2022/07/11 20:48
     */
    @GetMapping("/upper/")
    public XmResultJson<List<GroupLevelUpperVO>> getGroupLevelUpper(@RequestParam(value = "groupID", required = false) String groupId) {
        String orgCode = SecurityContextHolder.getToken().getOrgCode();
        String userId = SecurityContextHolder.getToken().getUserId();
        // 获取某个组所在层级及以上层级
        ServiceResult<List<UserGroupLevelDTO>> result = userGroupLevelService.getGroupLevelUpper(groupId, orgCode, userId);
        if (result.isSuccess() && Objects.nonNull(result.getData())) {
            return XmResultJson.success(UserGroupLevelConverter.levelDTOToUpperVO(result.getData()));
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());
    }


    /**
     * 保存层级数据
     */
    @XmAuth
    @PutMapping("/{levelId:[a-fA-F0-9]{24}}")
    public XmResultJson groupLevel(@PathVariable String levelId, @RequestBody JSONObject jsonObject) {
        TokenDTO currentToken = SecurityContextHolder.getToken();
        return XmResultJson.handleServiceResult(userGroupLevelService.putGroupLevel(currentToken, levelId, jsonObject));
    }

}
